package com.pantuo.sys.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.pantuo.common.utils.HttpClientPool;
import com.pantuo.sys.bo.UpdateInfo;
import com.pantuo.sys.dao.SfzLogDao;
import com.pantuo.sys.pojo.Log;
import com.pantuo.sys.service.UpdateCardIdAndName;
import javafx.beans.binding.When;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 炳秦
 * @Date: 2021/10/26/11:01
 * @Description:
 */
@Service
public class UpdateCardIdAndNameImpl implements UpdateCardIdAndName {

    @Autowired
    private SfzLogDao sfzLogDao;
    /***
    * @Description: 定时分析刷卡日志表，将身份证号码和姓名不全的辅助修正
    * @Param: []
    * @return: void
    * @Author: 炳秦
    * @Date: 2021/10/26 11:02
    */
    @Scheduled(cron = "0/60 * 8-22 * * * ")
    @Override
    public void analysisCardIdAndName() {
        String url = "jdbc:mysql://localhost:3306/oa_data3?serverTimezone=GMT%2B8&characterEncoding=utf8";
        String user = "root";
        String password = "pantuo1709";
        Connection conn = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String currentDate = sdf.format(new Date());
        //String currentDate = "2021-10";
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(url, user, password);
            String sql = "SELECT id, log_s FROM tn_sfzlog WHERE lineName_s IS NOT NULL AND bind_i = 1 AND update_i = 0 AND r_s = '1' AND created_dt LIKE '"+currentDate+"%' ";
            statement = conn.prepareStatement(sql);
            statement.setFetchSize(Integer.MIN_VALUE);
            resultSet = statement.executeQuery();
            while (resultSet.next()){
                //取出id，后续更新根据id更新
                int id = resultSet.getInt("id");
                String log_s = resultSet.getString("log_s");
                JSONArray jsonArray = JSONObject.parseObject(log_s).getJSONArray("words_result");
                //取出名字(未处理前的名字)
                String nameBefore = jsonArray.getJSONObject(0).get("words").toString();
                System.out.println("处理前名字："+nameBefore);
                System.out.println("处理前id："+id);
                String actualName = null;

                //如果nameBefore为“优待证”，则直接将状态（update_i）置为已修改（1为已修改，0为未修改）
                if("优待证".equals(nameBefore)){
                    sfzLogDao.updateStateById(id);
                }

                //不包含名的不分析
                if (nameBefore.contains("名") && nameBefore.length() >= 3){
                    actualName = nameBefore.split("名")[1];
                    //包含名且身份证长度满足18的直接取出更新
                    String actualCardId = getCardId(log_s);
                    if (getCardId(log_s).length() == 18){
                        Log log = new Log();
                        log.setId(id);
                        log.setAfterUpdateName_s(actualName);
                        log.setAfterUpdateCardId_s(actualCardId);
                        log.setUpdate_i(1);
                        sfzLogDao.updateSfzLog(log);
                    }else {//不满足18位的根据名字查询，尽量找出身份证为18位的
                        List<Map<String, Object>> logsList = sfzLogDao.findObjectByNameOrCardId(actualName);
                        //如果logsList是null，说明是第一次刷卡，那么直接取出第一次刷卡的身份证号进行更新
                        if (logsList.size() == 1) {
                            //取出该记录的身份证号
                            String cardId = getCardId(log_s);
                            Log log = new Log();
                            log.setAfterUpdateName_s(actualName);
                            log.setAfterUpdateCardId_s(cardId);
                            log.setId(id);
                            log.setUpdate_i(1);
                            sfzLogDao.updateSfzLog(log);
                        }else {
                            //对查询出来该乘客所有刷卡记录做分析，取出其身份证号满足18位的
                            String afterUpdateCardId_s = null;
                            for (Map<String, Object> map : logsList) {
                                String logs = (String) map.get("log_s");
                                String cardId = getCardId(logs);
                                //发现有身份证为18的记录下来并停止遍历
                                if (cardId.length() == 18){
                                    afterUpdateCardId_s = cardId;
                                    break;
                                }
                            }
                            //没找到长度为18的则找出大于等于12的
                            if (afterUpdateCardId_s == null){
                                for (Map<String, Object> map : logsList) {
                                    String logs = (String) map.get("log_s");
                                    String cardId = getCardId(logs);
                                    //发现有身份证为18的记录下来并停止遍历
                                    if (cardId.length() >= 12){
                                        afterUpdateCardId_s = cardId;
                                        break;
                                    }
                                }
                            }
                            Log log = new Log();
                            log.setId(id);
                            log.setAfterUpdateName_s(actualName);
                            log.setUpdate_i(1);
                            log.setAfterUpdateCardId_s(afterUpdateCardId_s);
                            sfzLogDao.updateSfzLog(log);
                        }
                    }
                }else {
                    //对未包含'名'字的姓名选择处理身份证
                    String cardId = getCardId(log_s);
                    System.out.println("身份证："+cardId);
                    if (cardId.length() >= 10){
                        List<Map<String, Object>> logsList = sfzLogDao.findObjectByNameOrCardId(cardId);
                        System.out.println("logsList："+logsList);
                        if (logsList.size() == 1){
                            Log log = new Log();
                            log.setId(id);
                            log.setAfterUpdateName_s(getNameNotIncludedMing(log_s));
                            log.setAfterUpdateCardId_s(cardId);
                            log.setUpdate_i(1);
                            sfzLogDao.updateSfzLog(log);
                        }else {
                            Log log = new Log();
                            for (Map<String, Object> map : logsList) {
                                String logs = (String) map.get("log_s");
                                actualName = getName(logs);
                                if (actualName != null){
                                    log.setAfterUpdateName_s(actualName);
                                    break;
                                }
                            }
                            //经过身份证查询刷卡记录的所有数据后取不到包含'名'字的姓名则直接将该记录的第一个words作为名字
                            if (actualName == null){
                                log.setAfterUpdateName_s(getNameNotIncludedMing(log_s));
                            }
                            log.setId(id);
                            log.setAfterUpdateCardId_s(cardId);
                            log.setUpdate_i(1);
                            sfzLogDao.updateSfzLog(log);
                        }
                    }
                }
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    private static List<String> signList = new ArrayList<>();
    static {
        signList.add(":。");
        signList.add("■。");
        signList.add("。。");
        signList.add(":");
        signList.add("8");
        signList.add("。");
        signList.add("《");
        signList.add("■");
        signList.add("“。");
        signList.add("题。");
    }
    
    /***
    * @Description: 对优化后姓名存在特俗标点的每隔一小时处理一次
    * @Param: []
    * @return: void
    * @Author: 炳秦
    * @Date: 2022/2/24 15:19
    */
    @Override
    public void analysisAfterUpdateName() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String currentDate = sdf.format(new Date());
        Integer minId = sfzLogDao.selectMinId(currentDate);

    }


    public String getCardId(String logs){
        JSONArray jsonArray = JSONObject.parseObject(logs).getJSONArray("words_result");
        String cardIdBefore = jsonArray.getJSONObject(jsonArray.size() - 1).get("words").toString();
        if(cardIdBefore.length() <= 7){
            cardIdBefore = jsonArray.getJSONObject(jsonArray.size() - 2).get("words").toString();
        }
        String cardId = getNumberFromString(cardIdBefore);
        return cardId;
    }

    public String getName(String logs){
        JSONArray jsonArray = JSONObject.parseObject(logs).getJSONArray("words_result");
        String nameBefore = jsonArray.getJSONObject(0).get("words").toString();
        String actualName = null;
        if (nameBefore.contains("名") && nameBefore.length() >= 3){
            actualName = nameBefore.split("名")[1];
        }
        return actualName;
    }

    //获取不好含'名'字的姓名
    public String getNameNotIncludedMing(String logs){
        JSONArray jsonArray = JSONObject.parseObject(logs).getJSONArray("words_result");
        String nameBefore = jsonArray.getJSONObject(0).get("words").toString();
        /*String actualName = null;
        if (nameBefore.contains("名") && nameBefore.length() >= 3){
            actualName = nameBefore.split("名")[1];
        }*/
        return nameBefore;
    }


    public String getNumberFromString(String str) {
        String regEx="[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return  m.replaceAll("").trim();//3303821986   0618
    }
}
